﻿using DevExpress.Data.Filtering;
using DevExpress.Data.Filtering.Helpers;
using Volo.Abp.DependencyInjection;
using YAPACS.BusinessObjects.Exams;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Workflows.Register;

public class AdvancedSearchExpression : WorkflowBase, IAdvancedSearchExpression, ITransientDependency
{
    protected override async Task<WorkflowOutput> InvokeCoreAsync(WorkflowInput input)
    {
        string condition = " where 1=1 ";
        const string key = "Input";
        CriteriaOperator criteriaOperator = null;
        if (input.ContainsKey(key) && input.GetValueOrDefault(key) is Dictionary<string, object> search)
        {
            //默认查询条件
            //检查号，姓名，设备类型（选择）,设备（选择），登记时间段
            //返回CriteriaOperator
            if (!search.ContainsKey("examTimeRange"))
            {
                search.Add("examTimeRange", string.Join(",", [DateTime.Today.ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]));
            }
            foreach (var item in search)
            {
                //检查号
                if (item.Key.EqualsIgnoreCase("AccessionNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.AccessionNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and AccessionNumber=@AccessionNumber";
                    }
                }
                //患者姓名
                if (item.Key.EqualsIgnoreCase("Name"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => e.Patient != null));
                        if (value.Contains('*'))
                        {
                            var array = value.Split('*');
                            foreach (var arr in array)
                            {
                                if (!string.IsNullOrWhiteSpace(arr))
                                {
                                    var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient.Name.Contains(arr));
                                    criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                                }
                            }
                        }
                        else
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient.Name == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and PatientName=@Name";
                        }
                    }
                }
                //性别
                if (item.Key.EqualsIgnoreCase("PatientSex"))
                {
                    if (int.TryParse(item.Value?.ToString(), out int sex))
                    {
                        var value = (PatientSex)sex;
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.Sex == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and Sex='{(value == PatientSex.Female ? "女" : value == PatientSex.Male ? "男" : "不详")}'";
                    }
                }
                //患者Id
                if (item.Key.EqualsIgnoreCase("PatientId"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.PatientId == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and PatientId=@PatientId";
                    }
                }
                //呼叫编号
                if (item.Key.EqualsIgnoreCase("CallNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamQueuing != null && e.ExamQueuing.CallNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                    }
                }
                //预约编号
                if (item.Key.EqualsIgnoreCase("AppointmentNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamAppointment != null && e.ExamAppointment.AppointmentNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                    }
                }
                //门诊号
                if (item.Key.EqualsIgnoreCase("OutPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.OutPatientNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and OutPatientNumber=@OutPatientNumber";
                    }
                }
                //住院号
                if (item.Key.EqualsIgnoreCase("InPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.InPatientNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and InPatientNumber=@InPatientNumber";
                    }
                }
                //体检号
                if (item.Key.EqualsIgnoreCase("PhysicalExamNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.PhysicalExamNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and PhysicalExamNumber=@PhysicalExamNumber";
                    }
                }
                //检查时间（范围）//创建时间
                string examTimeRange = default;
                if (item.Key.EqualsIgnoreCase("ExamTimeRange"))
                {
                    examTimeRange = item.Value as string;
                    if (string.IsNullOrWhiteSpace(examTimeRange))
                    {
                        examTimeRange = string.Join(",", [DateTime.Today.ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]);
                    }
                    var timeRange = examTimeRange.Split(',');
                    var startTime = DateTime.Parse(timeRange[0]).Date;
                    var endTime = DateTime.Parse(timeRange[1]).AddDays(1).Date;
                    criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => (e.ExamQueuing != null && e.ExamQueuing.QueuingTime >= startTime && e.ExamQueuing.QueuingTime < endTime) || (e.ExamTime != null && e.ExamTime >= startTime && e.ExamTime < endTime) || (e.ExamQueuing == null && e.ExamTime == null && e.RegisterTime >= startTime && e.RegisterTime < endTime)));
                    condition += " and ((ExamTime>=@StartTime and ExamTime< @EndTime) or (RegisterTime>=@StartTime and RegisterTime< @EndTime))";
                }
                //联系方式（联系方式1和联系方式2）
                if (item.Key.EqualsIgnoreCase("PhoneNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && (e.Patient.PhoneNumber == value || e.Patient.PhoneNumber2 == value));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and PhoneNumber=@PhoneNumber";
                    }
                }
                //证件号码
                if (item.Key.EqualsIgnoreCase("IdCardNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.IdCardNumber == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += " and IdCardNumber=@IdCardNumber";
                    }
                }
                //检查项目（多选）
                if (item.Key.EqualsIgnoreCase("ExamItems"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var examItems = value.Split(',').Select(Guid.Parse).Take(10);
                        foreach (var examItem in examItems)
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamItems.Any(g => g.Oid == examItem));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex('{examItem}',ExamItems)>0 ";
                        }
                    }
                }
                //申请科室（多选）
                if (item.Key.EqualsIgnoreCase("ApplyDepartments"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var applyDepartments = value.Split(',').Select(Guid.Parse).Take(10);
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ApplyDepartment != null && applyDepartments.Contains(e.ApplyDepartment.Oid));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and charindex(ApplyDepartment,@ApplyDepartments)>0 ";
                    }
                }
                //检查部位（多选）
                if (item.Key.EqualsIgnoreCase("ExamBodyParties"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var examBodyParties = value.Split(',').Select(Guid.Parse).Take(10);
                        foreach (var examBodyParty in examBodyParties)
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamBodyParties.Any(g => g.Oid == examBodyParty));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex('{examBodyParty}',ExamBodyParties)>0 ";
                        }
                    }
                }
                //检查结果（单选）
                if (item.Key.EqualsIgnoreCase("ExamResult"))
                {
                    var value = (ExamResult)item.Value;
                    var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ExamResult == value);
                    criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                    condition += $" and ExamResult='{(value == ExamResult.Negative ? "阴性" : value == ExamResult.Positive ? "阳性" : "不详")}'";
                }
                //检查设备（多选）
                if (item.Key.EqualsIgnoreCase("ExamDevices"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var examDevices = value.Split(',').Select(Guid.Parse).Take(10);
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamDevice != null && examDevices.Contains(e.ExamDevice.Oid));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and charindex(ExamDevice,@ExamDevices)>0 ";
                    }
                }
                //检查类别（多选）
                if (item.Key.EqualsIgnoreCase("ExamCategories"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var examCategories = value.Split(',').Select(Guid.Parse).Take(10);
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamCategory != null && examCategories.Contains(e.ExamCategory.Oid));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and charindex(ExamCategory,@ExamCategories)>0 ";
                    }
                }
                //设备类型（多选）
                if (item.Key.EqualsIgnoreCase("DeviceTypes"))
                {
                    var value = item.Value as string;
                    if (!(string.IsNullOrWhiteSpace(value) || value == "全部"))
                    {
                        var deviceTypes = value.Split(',').Take(10);
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.DeviceType != null && deviceTypes.Contains(e.DeviceType.Code));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and charindex(DeviceType,@DeviceTypes)>0 ";
                    }
                }
                //医疗机构
                if (item.Key.EqualsIgnoreCase("Institution"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var institutions = value.Split(',');
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Department != null && e.Department.Institution != null && institutions.Contains(e.Department.Institution.Code));
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                    }
                }
                //报告状态
                if (item.Key.EqualsIgnoreCase("ExamStatus"))
                {
                    var value = item.Value as string;
                    if (!(string.IsNullOrWhiteSpace(value) || value == "全部"))
                    {
                        var examStatusArr = value.Split(',');
                        CriteriaOperator statuscriteriaOperator = null;
                        if (examStatusArr.Contains("已预约"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamStatus == ExamStatus.Appointment);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("等候中"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamQueuing != null && e.ExamQueuing.Status == ExamQueuingStatus.Wait);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("呼叫中"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamQueuing != null && e.ExamQueuing.Status == ExamQueuingStatus.Ready);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("已过号"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamQueuing != null && e.ExamQueuing.Status == ExamQueuingStatus.Skip);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("已检查"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamStatus == ExamStatus.Report);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("已报告"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamStatus == ExamStatus.Completed);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("未打印"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => new ExamStatus[] { ExamStatus.Report, ExamStatus.Completed }.Contains(e.ExamStatus) && e.Report != null && e.Report.PrintingTimes == 0);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        if (examStatusArr.Contains("已打印"))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => new ExamStatus[] { ExamStatus.Report, ExamStatus.Completed }.Contains(e.ExamStatus) && e.Report != null && e.Report.PrintingTimes > 0);
                            statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                        }
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, statuscriteriaOperator);
                    }
                }
            }

            //ParameterExpression parameter = Expression.Parameter(typeof(Exam), "e");

            //// 创建一个空的 Expression
            //Expression body = Expression.Constant(true);

            //foreach (var kvp in search)
            //{
            //    // 创建成员表达式
            //    MemberExpression member = Expression.PropertyOrField(parameter, kvp.Key);

            //    // 创建常量表达式
            //    ConstantExpression constant = Expression.Constant(Convert.ChangeType(kvp.Value,member.Type), member.Type);

            //    // 创建相等表达式
            //    BinaryExpression equal = Expression.Equal(member, constant);

            //    // 使用 AndAlso 方法组合表达式
            //    body = Expression.AndAlso(body, equal);
            //}

            //// 构建 Lambda 表达式
            //Expression<Func<Exam, bool>> lambda = Expression.Lambda<Func<Exam, bool>>(body, parameter);
            //input.Add("Output", lambda);
        }
        if (criteriaOperator.ReferenceEqualsNull())
        {
            criteriaOperator = CriteriaOperator.FromLambda<Exam>(e => false);
        }
        input.Add("Output", criteriaOperator);
        input.Add("ArchiveOutput", condition);
        return await Task.FromResult(new WorkflowOutput
        {
            Success = true
        });
    }
}
